﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CMPPProtocol.Message;

namespace CMPPProtocol
{
    /// <summary>
    /// CMPP协议策略
    /// </summary>
    public abstract class BaseCMPPProtocol : ProtocolStrategy
    {

        internal override byte[] GetBytes(ICMPP_Protocol message)
        {
            Type msgType = message.GetType();

            #region CMPP_HEAD
            if (msgType == typeof(CMPP_HEAD))
            {
                byte[] buffer;
                byte[] temp;

                CMPP_HEAD head = message as CMPP_HEAD;
                buffer = new byte[12];
                temp = BitConverter.GetBytes(head.TotalLength);
                Array.Reverse(temp);
                temp.CopyTo(buffer, 0);

                temp = BitConverter.GetBytes(head.CommandID);
                Array.Reverse(temp);
                temp.CopyTo(buffer, 4);

                temp = BitConverter.GetBytes(head.SequenceID);
                Array.Reverse(temp);
                temp.CopyTo(buffer, 8);

                return buffer;
            }
            #endregion

            #region CMPP_CONNECT
            if (msgType == typeof(CMPP_CONNECT))
            {
                byte[] buffer;
                byte[] temp;
                int iPos = 0;

                CMPP_CONNECT msg = message as CMPP_CONNECT;
                msg.Head.TotalLength = 39;
                buffer = new byte[39];

                temp = GetBytes(msg.Head);
                temp.CopyTo(buffer, iPos);
                iPos += temp.Length;

                temp = Convert.ToBytes(msg.SourceAddress, CMPPEncoding.CODING_ASCII);
                temp.CopyTo(buffer, iPos);
                iPos += 6;

                msg.AuthenticatorSource.CopyTo(buffer, iPos);
                iPos += msg.AuthenticatorSource.Length;

                buffer[iPos] = msg.Version;
                iPos++;

                temp = BitConverter.GetBytes(msg.TimeStamp);
                Array.Reverse(temp);
                temp.CopyTo(buffer, iPos);
                iPos += temp.Length;

                return buffer;
            }
            #endregion

            #region CMPP_DELIVER_RESP

            if (msgType == typeof(CMPP_DELIVER_RESP))
            {
                byte[] buffer = null;
                Byte[] temp = null;
                int iPos = 0;
                CMPP_DELIVER_RESP msg = message as CMPP_DELIVER_RESP;



                msg.Head.TotalLength = 24;
                buffer = new Byte[msg.Head.TotalLength];


                temp = this.GetBytes(msg.Head);
                temp.CopyTo(buffer, iPos);
                iPos += temp.Length;


                temp = BitConverter.GetBytes(msg.MsgID);
                temp.CopyTo(buffer, iPos);
                iPos = iPos + temp.Length;


                temp = BitConverter.GetBytes(msg.Result);
                Array.Reverse(temp);
                temp.CopyTo(buffer, iPos);
                iPos = iPos + temp.Length;

                return buffer;

            }

            #endregion

            #region CMPP_ACTIVE_TEST
            if (msgType == typeof(CMPP_ACTIVE_TEST))
            {
                CMPP_ACTIVE_TEST msg = message as CMPP_ACTIVE_TEST;
                msg.Head.TotalLength = 12;
                return this.GetBytes(msg.Head);
            }
            #endregion

            #region CMPP_CANCEL
            if (msgType == typeof(CMPP_CANCEL))
            {
                byte[] buffer;
                byte[] temp;
                int iPos = 0;

                CMPP_CANCEL msg = message as CMPP_CANCEL;
                msg.Head.TotalLength = 20;
                buffer = new Byte[msg.Head.TotalLength];

                temp = this.GetBytes(msg.Head);
                temp.CopyTo(buffer, iPos);
                iPos += temp.Length;

                temp = BitConverter.GetBytes(msg.MsgID);
                temp.CopyTo(buffer, iPos);
                iPos += temp.Length;

                return buffer;
            }
            #endregion

            return null;
        }

        internal override T FromBytes<T>(byte[] buffer)
        {
            Type msgType = typeof(T);
            T t = new T();

            #region CMPP_ACTIVE_TEST_RESP

            if (msgType == typeof(CMPP_ACTIVE_TEST_RESP))
            {
                CMPP_ACTIVE_TEST_RESP msg = t as CMPP_ACTIVE_TEST_RESP;
                msg.Reserved = buffer[0];
            }

            #endregion
            return t;
        }
    }
}
